Inventory Reporting & Management
Background
The Inventory Reporting API is useful to create detailed inventory reports of sites, rooms, and devices.
Some examples include device aggregations, device queries, device count, and site & room information.
Remember that the GraphQL Explorer is tied to your user's authentication when testing the sample queries below. If your user can access multiple tenants, the query response is aggregate data from those tenants.
If you need to test within a specific tenant, we've exposed an option to use Client Credentials
- also known as an API Connection
. To select a set of credentials, click the Client Credentials
toggle in the upper left-hand corner of the page, select the credentials you want to use from the dropdown list, and then continue on with your testing.
Deprecated Queries
Poly Lens APIs have evolved over recent months as we've worked to optimize the device querying experience.
There are two queries which are now deprecated, devices
and searchDevices
. While both of these queries still "work", they're not as optimized to handle querying large batches of device data. The new deviceSearch
query offers a better way to handle pagination and supports returning results of more than 10k entries.
If you've begun development using either of the prior queries, it would be worth the effort to update your queries to use deviceSearch
moving forward. deviceSearch
fields use edges
and nodes
- this is a relational structure that supports pagination and is different than the legacy devices
query. deviceSearch
also uses the DeviceFindArgs
type for argument parameters. You'll see some examples of this structure in our queries below.
Querying Devices
We'll start by running a query to return information pertaining to devices in our tenant. There are many fields available, but in this example we'll focus on returning the following fields: name
, hardwareFamily
, softwareVersion
, activeApplicationName
, hasPeripherals
, and connections
.
By default, the number of devices returned is 10. However, if you need more than 10 devices returned, you can use the pageSize
variable to set a different amount. The minimum is 1 and the maximum is 5000. When you set the number of devices returned you can use the pageInfo
fields to return totalCount
, countOnPage
, nextToken
, and hasNextPage
- all which are helpful when dealing with pagination.
To keep the sample response concise, we'll change the number to 2 in our examples.
Query Devices Using deviceSearch
Test this query in the GraphQL Playground
query allDevices($params: DeviceFindArgs) {
deviceSearch(params: $params) {
edges {
node {
name
hardwareFamily
hardwareModel
softwareVersion
activeApplicationName
hasPeripherals
connections {
connected
allPeripheralsLinked
name
}
}
}
pageInfo {
totalCount
countOnPage
nextToken
hasNextPage
}
}
}
Variables
{
"params": {
"pageSize": 2,
"sort": {
"fields": [
{
"direction": "ASC",
"name": "id"
}
]
}
}
}
Sample Response
{
"data": {
"deviceSearch": {
"edges": [
{
"node": {
"name": "Poly Lens Desktop",
"hardwareFamily": "Lens App Family",
"hardwareModel": "Lens Desktop",
"softwareVersion": "1.0.7",
"activeApplicationName": null,
"hasPeripherals": null,
"connections": [
{
"connected": true,
"allPeripheralsLinked": false,
"name": "BT700"
}
]
}
},
{
"node": {
"name": "Savi 8200 Office Series",
"hardwareFamily": "Savi Family",
"hardwareModel": "Savi 8200 Office Series",
"softwareVersion": "3863",
"activeApplicationName": null,
"hasPeripherals": null,
"connections": []
}
}
],
"pageInfo": {
"totalCount": 3485,
"countOnPage": 2,
"nextToken": "MmozNTliZGxslkbnQxODNu",
"hasNextPage": true
}
}
}
}
Querying Specific Device Details
The deviceSearch
query is incredibly powerful as it provides insight for all devices in a tenant. You'll likely need to aggregate this data in different ways. To support various levels of granularity, we provide an expansive list of filter options. We'll take a look at a few of these filter options in the next examples.
Let's say we're building a page for Room Video devices and want to know which devices are running in Zoom Mode. We can accomplish this by targeting the activeApplicationName
field in the deviceSearch
query.
For our query we want to know the: device name
, serial number
, hardware model
, activeApplicationName
(Provider Mode), activeApplicationVersion
(Provider APK Version), and room name
& floor
they're assigned to.
We'll do this by passing in two filter
variables: contains
and field
. Effectively we're saying for all devices, look at the activeApplicationName
field and if it contains
"Zoom" return it to me.
Note: The provider name passed into the contains
field is case sensitive.
Query Devices Running Zoom Rooms
Test this query in the GraphQL Playground
query zoomDevices($params: DeviceFindArgs) {
deviceSearch(params: $params) {
edges {
node {
name
serialNumber
hardwareModel
activeApplicationName
activeApplicationVersion
room {
name
floor
}
}
}
pageInfo {
totalCount
countOnPage
nextToken
hasNextPage
}
}
}
Variables
{
"params": {
"pageSize": 2,
"filter": {
"contains": "Zoom",
"field": "activeApplicationName"
},
"sort": {
"fields": [
{
"direction": "ASC",
"name": "id"
}
]
}
}
}
Sample Response
A few things to note in the query response:
- The
activeApplicationVersion
field - The ability to see the application version is helpful for folks managing Poly OS devices running Ecosystem Partner APKs. - The
nodes
returned - We're limiting thecountOnPage
to 2 items (for conciseness). But if you look at thetotalCount
you'll see we have 65 items running Zoom Rooms mode.
{
"data": {
"deviceSearch": {
"edges": [
{
"node": {
"name": "DFR StudioX70",
"serialNumber": "superSecretSerialNumber",
"hardwareModel": "Studio X70",
"activeApplicationName": "Zoom Rooms",
"activeApplicationVersion": "5.13.5.2468",
"room": {
"name": "Jedi Enclave",
"floor": "2"
}
}
},
{
"node": {
"name": "DFR StudioX30",
"serialNumber": "superSecretSerialNumber",
"hardwareModel": "Studio X30",
"activeApplicationName": "Zoom Rooms",
"activeApplicationVersion": "5.12.0.1972",
"room": {
"name": "Skywalker Ranch",
"floor": "4"
}
}
}
],
"pageInfo": {
"totalCount": 65,
"countOnPage": 2,
"nextToken": "NHU2MTybWpic2Jt",
"hasNextPage": true
}
}
}
}
Query Devices with the OR:
Filter
If you have deployed Poly Video devices running either Native Zoom Rooms or Microsoft Teams Rooms, you might want to build a view to display this information. While there are many ways to implement this on the front end, you'll need to build a query to return the devices with this data. You can accomplish this using the OR:
filter.
Test this query in the GraphQL Playground
query msftAndZoomDevices($params: DeviceFindArgs) {
deviceSearch(params: $params) {
edges {
node {
name
serialNumber
hardwareModel
activeApplicationName
activeApplicationVersion
room {
name
floor
}
}
}
pageInfo {
countOnPage
totalCount
hasNextPage
nextToken
}
}
}
Variables
{
"params": {
"pageSize": 2,
"filter": {
"OR": [
{
"contains": "Zoom",
"field": "activeApplicationName"
},
{
"contains": "Microsoft",
"field": "activeApplicationName"
}
]
},
"sort": {
"fields": [
{
"direction": "ASC",
"name": "id"
}
]
}
}
}
Sample Response
{
"data": {
"deviceSearch": {
"edges": [
{
"node": {
"name": "DFR StudioX30",
"serialNumber": "superSecretSerialNumber",
"hardwareModel": "Studio X30",
"activeApplicationName": "Microsoft Teams",
"activeApplicationVersion": "1449/1.0.96.2022120503",
"room": {
"name": "Skywalker Ranch",
"floor": "3"
}
}
},
{
"node": {
"name": "DFR StudioX70",
"serialNumber": "superSecretSerialNumber",
"hardwareModel": "Studio X70",
"activeApplicationName": "Zoom Rooms",
"activeApplicationVersion": "5.13.5.2468",
"room": {
"name": "Jedi Enclave",
"floor": "2"
}
}
}
],
"pageInfo": {
"countOnPage": 2,
"totalCount": 33,
"hasNextPage": true,
"nextToken": "cHknJlcjBueTMwZg=="
}
}
}
}
Query Devices with the OR:
& AND:
Filters
If you wanted to take the example above one step further and build the ability to filter your devices on the Provider Mode (activeApplicationName
) and the Hardware Model (hardwareModel
) you can use the AND:
& OR:
filters. In the following example we're saying, if the device is running in Zoom Rooms or Microsoft Teams mode and it's a Studio X50, return it to me.
Test this query in the GraphQL Playground
query zoomMsftDevices($params: DeviceFindArgs) {
deviceSearch(params: $params) {
edges {
node {
name
serialNumber
hardwareModel
activeApplicationName
activeApplicationVersion
room {
name
floor
}
}
}
pageInfo {
countOnPage
totalCount
hasNextPage
nextToken
}
}
}
Variables
{
"params": {
"pageSize": 2,
"filter": {
"AND": [
{
"contains": "Studio X50",
"field": "hardwareModel"
},
{
"OR": [
{
"contains": "Zoom",
"field": "activeApplicationName"
},
{
"contains": "Microsoft",
"field": "activeApplicationName"
}
]
}
]
},
"sort": {
"fields": [
{
"direction": "ASC",
"name": "id"
}
]
}
}
}
Sample Response
{
"data": {
"deviceSearch": {
"edges": [
{
"node": {
"name": "DFR Studio X50",
"serialNumber": "superSecretSerialNumber",
"hardwareModel": "Studio X50",
"activeApplicationName": "Microsoft Teams",
"activeApplicationVersion": "1449/1.0.96.2022120503",
"room": {
"name": "Bantha Plains",
"floor": "2"
}
}
},
{
"node": {
"name": "DFR Studio X50",
"serialNumber": "superSecretSerialNumber",
"hardwareModel": "Studio X50",
"activeApplicationName": "Zoom Rooms",
"activeApplicationVersion": "5.13.6.2489",
"room": {
"name": "Oga's Cantina",
"floor": "3"
}
}
}
],
pageInfo": {
"countOnPage": 2,
"totalCount": 15,
"hasNextPage": true,
"nextToken": "Z2F4eHprc3eG92ZWE0NGt4"
}
}
}
}
Query CCX Hardware Revisions
If you're using Poly Lens to manage your CCX inventory and need to know which CCX 400 & 500 hardware revisions you've deployed, you can use the Lens APIs to aggregate this data.
There are two ways to use the Lens APIs:
- Use the GraphQL Playground to run the query and export the results to
.csv
- This approach is best for those who don't write code/scripts
- It involves using Excel to format the
.csv
results
- Grab the example Query and Arguments from the GraphQL Playground and implement into your scripting language of choice
- This is more upfront work but removes the need to parse the data through external tools (like Excel)
This article details using the GraphQL Playground to query the data and export the results to .csv
For those using the GraphQL Playground, we'll break the process down into these steps:
It's important to note that the GraphQL Playground uses User Authentication
. If your user can access multiple Poly Lens tenants, the query response is aggregate data from those tenants. If you're in this position and need to isolate the scope to a single tenant, you can create an API Connection or pass the tenantId
into the arguments of the example query we've pre-configured for you.
Query Structure
We'll use the deviceSearch
query to return each CCX's name
, hardwareModel
, macAddress
, hardwareRevision
, softwareVersion
, site
, & room
. These fields should provide enough information to accomplish the task. However, if you don't have CCXs assigned to a room or site, or don't need/want certain fields we've included, you can remove them from the query and proceed.
In the Variables
section, we filter by hardwareModel
to return only CCX 400 and 500 models. pageSize
is set to return 500 CCXs at a time to avoid rate-limiting. If you need to know how many CCXs you have, you can run the query and look at the totalCount
field.
If the totalCount
is less 500, refer to Tenants with < 500 CCXs
If the totalCount
exceeds 500, refer to the Tenants with > 500 CCXs
Access this query in the GraphQL Playground
Tenants with < 500 CCXs
If pageCount
returned less than 500 devices, click the table icon in the Response
section of the UI. The results will appear in a table view and expose a .csv
download button. Download the .csv
and proceed to Formatting the .csv
Data in Excel
Tenants with > 500 CCXs
The pageInfo
fields contain the information required to use pagination
. Of the four fields, nextToken
is the one we need to use.
The Variables
> params
> nextToken
field will be null
the first time you run the query.
Now, run the query and look at the Response
section. If the totalCount
exceeds the pageSize
, nextToken
will contain an alphanumeric string.
Click the table
icon and look at the edges
row. You'll see an option to download the .csv
results.
Copy the nextToken
string from the query response and paste it into the Variables
> params
> nextToken
field before running the query to fetch the next batch of results. Make sure you download the .csv
each time you run the query and fetch the next batch of results.
Continue copying the nextToken
, running the query, and downloading the csv
until the response returns nextToken
: null
.
Formatting the .csv
Data in Excel
Each CCX we've queried has the same key
and value
format. The goal is to create a usable Excel table by filtering/parsing the unnecessary characters, removing the duplicate keys
, and creating a column with a single key
(as a header) for each CCX corresponding value
.
This section covers the more accessible more manual way to format the query results in Excel. If you're an Excel power user, this section won't be helpful for you. Feel free to skip it and perform the Excel formatting magic of your choice.
For the rest of us, we'll start by ensuring we have a single .csv
as our primary document. If you have < 500 devices and only one .csv
file, congrats, you saved a little work and should proceed to the Text to Columns Wizard
If you have > 500 devices and have downloaded multiple .csv
files, open the first one and delete row A1
. This file will be our primary working document.
For each additional .csv
, the process remains the same. Open the file and cut/paste all rows (except A1
) into the primary document. After you've moved all rows to the primary document, the result/structure of the file will look similar to this.
Text to Columns Wizard
The data for each device is in the first cell of each row, even though it spans across the table. To filter and parse this information, select all in Column A
, click the Data
tab, and click Text to Columns
Text to Columns
has limitations, so we can't parse all characters in a single step. However, it gets us most of the way there.
Text to Columns - Step 1 of 3: Choose the Delimited
character type and click Next
Text to Columns - Step 2 of 3: In the Delimiters
section, select Comma
, Other
, and add a colon (:) into the field.
Text to Columns - Step 3 of 3: Make sure General
is selected in the Column data format
field. Click Finish.
Creating Column Headers
The next step is to create column headers for the values
. First, insert a new row at the top of the table. Then, you can cut/paste the key
into the row's corresponding column or type it manually. The .csv
splits the site
name
and room
name
into separate columns. Combine these values into a single column header. Now, you can select and delete all columns containing the same key.
Removing Remaining Characters
The }
is the last character we need to remove. Using Find and Replace
, add a }
in the Find what
field and a blank space in the Replace with
field. Click Replace All
and the result will be a cleanly formatted table.
Format as Table
Select all the data cells and use Format as Table
to make the table easier to read and filter. During this step, make sure to select My table has headers
.
And just like that, you've used the GraphQL Playground to query data from your Poly Lens tenant, parsed the results, and created a usable table to drill into the details. Nice work! 👏🏼
Please reach out if you have specific content requests or questions.